package com.ecoolex.discount.sales.core.service;

import com.ecoolex.discount.sales.core.external.QuanMaoExternalService;
import com.ecoolex.discount.sales.core.external.pojo.QuanMaoOrderInfo;
import com.ecoolex.discount.sales.core.manager.DiscountOrderDetailManager;
import com.ecoolex.discount.sales.core.manager.DiscountProductManager;
import com.ecoolex.discount.sales.core.manager.QuanMaoCardManager;
import com.ecoolex.discount.sales.core.manager.QuanMaoCardOrderManager;
import com.ecoolex.discount.sales.entity.*;
import com.ecoolex.discount.sales.enums.*;
import com.ecoolex.discount.sales.pojo.QuanMaoServiceProviderInfoDTO;
import com.ecoolex.framework.common.util.BizAssert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.common.util.CollectorUtil;
import com.ecoolex.framework.common.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

import static com.ecoolex.discount.sales.core.external.pojo.QuanMaoCardListResult.QuanMaoCardVoucher;
import static com.ecoolex.discount.sales.core.external.pojo.QuanMaoChannelInfoResult.QuanMaoChannelInfo;

@Service
public class QuanMaoService {

    private static final Logger log = LoggerFactory.getLogger(QuanMaoService.class);

    @Autowired
    private QuanMaoExternalService quanMaoExternalService;

    @Autowired
    private QuanMaoCardManager quanMaoCardManager;
    @Autowired
    private QuanMaoCardOrderManager quanMaoCardOrderManager;
    @Autowired
    private DiscountProductManager discountProductManager;
    @Autowired
    private DiscountOrderDetailManager discountOrderDetailManager;

    // 刷新账户状态
    // 刷新卡券状态
    public synchronized void refreshCards() {
        // 同步接口数据
        syncApiData();
        // 同步产品可用状态
        syncProductAvailableStatus();
    }

    public synchronized void refreshAccountStatus() {
        if (checkAccountState()) {
            // 合法的同步所有产品可用状态
            syncProductAvailableStatus();
        } else {
            // 不合法, 标记所有产品为不可用
            disableAllProduct();
        }
    }

    public QuanMaoServiceProviderInfoDTO getServiceProviderInfo() {
        QuanMaoChannelInfo channelInfo = quanMaoExternalService.channelInfo();
        QuanMaoServiceProviderInfoDTO result = new QuanMaoServiceProviderInfoDTO();
        channelInfo.setUserName(channelInfo.getUserName());
        channelInfo.setMobile(channelInfo.getMobile());
        channelInfo.setAccount(channelInfo.getAccount());
        return result;
    }

    private void disableAllProduct() {
        List<DiscountProductWithBLOBs> productList = discountProductManager.queryByServiceType(DiscountProductServiceType.QUAN_MAO);
        productList.forEach(product -> {
            // 检查状态是否与数据库数据相等, 不相等则更新
            if (DiscountProductAvailableStatus.DISABLE.notEqual(product.getAvailableStatus())) {
                discountProductManager.setDisableAvailable(product.getProductId(), this.getClass().getSimpleName());
            }
        });
    }

    private boolean checkAccountState() {
        // TODO 检查账户状态, 检查状态是否合法,检查余额是否足够
        QuanMaoChannelInfo channelInfo = quanMaoExternalService.channelInfo();
        return channelInfo.getAccount() >= 10;
    }

    private boolean verifyCanAddOrUpdate(QuanMaoCardVoucher card) {
        return Check.notNull(card.getCardNo())
                && Check.notNullOrTrimEmpty(card.getCardName())
                && Check.notNull(card.getCardType())
                && Check.notNull(card.getType())
                && Check.notNull(card.getStatus())
                && Check.notNull(card.getFaceValue())
                && Check.notNull(card.getPrice())
                ;
    }

    private void syncApiData() {
        // 直冲
        List<QuanMaoCardVoucher> rechargeCardList = quanMaoExternalService.cardList(1);
        // 券
        List<QuanMaoCardVoucher> voucherCardList = quanMaoExternalService.cardList(2);
        // 合并数据
        rechargeCardList.addAll(voucherCardList);
        // 已存在的卡
        List<QuanMaoCard> oldCardList = quanMaoCardManager.queryAll();
        rechargeCardList.forEach(card -> {
            // 检查是否能添加或者更新
            if (!verifyCanAddOrUpdate(card)) {
                return;
            }
            QuanMaoCard oldCard = oldCardList.stream().collect(CollectorUtil.first(old -> card.getCardNo().equalsIgnoreCase(old.getCardNo())));
            if (Check.isNull(oldCard)) {
                quanMaoCardManager.create(card, this.getClass().getSimpleName());
            } else {
                quanMaoCardManager.update(card, oldCard, this.getClass().getSimpleName());
                oldCardList.remove(oldCard);
            }
        });
        // 标记删除
        oldCardList.forEach(old -> quanMaoCardManager.setNotFoundSyncData(old, this.getClass().getSimpleName()));
    }

    private void syncProductAvailableStatus() {
        // 查询账户状态和账户是否有余额,或者最少余额, 如果不合理则需要下线所有礼品卡产品
        if (!checkAccountState()) {
            log.info("账户状态不合法, 停止更新产品状态");
        }

        List<QuanMaoCard> oldCardList = quanMaoCardManager.queryAll();
        oldCardList.forEach(card -> {
            DiscountProductAvailableStatus availableStatus = getDiscountProductAvailableStatus(card);
            // 查询关联的产品
            List<DiscountProductWithBLOBs> discountProductList = discountProductManager.queryByServiceTypeAndServiceDataId(DiscountProductServiceType.QUAN_MAO, card.getCardNo());
            discountProductList.forEach(product -> {
                // 检查状态是否与数据库数据相等, 不相等则更新
                if (availableStatus.notEqual(product.getAvailableStatus())) {
                    discountProductManager.setEnableAvailable(product.getProductId(), this.getClass().getSimpleName());
                }
            });
        });
    }

    private DiscountProductAvailableStatus getDiscountProductAvailableStatus(QuanMaoCard card) {
        QuanMaoCardDataStatus status = QuanMaoCardDataStatus.realValueOf(card.getDataStatus());
        // 产品的启用状态; 默认禁用
        if (QuanMaoCardDataStatus.NORMAL == status) {
            if (card.getStatus() == 1) {
                return DiscountProductAvailableStatus.ENABLE;
            }
        }
        return DiscountProductAvailableStatus.DISABLE;
    }

    public void validityVerify(DiscountProduct product) {
        BizAssert.isTrue(Check.notNullOrTrimEmpty(product.getServiceDataId()), "服务数据Id为空");
        QuanMaoCard card = quanMaoCardManager.getById(product.getServiceDataId());
        BizAssert.isTrue(Check.notNull(card), "券猫卡券不存在");
        DiscountProductDiscountMode discountMode = DiscountProductDiscountMode.realValueOf(product.getDiscountMode());
        // 如果券猫的券是充值
        if (QuanMaoCardType.RECHARGE.equal(card.getCardType())) {
            BizAssert.isTrue(discountMode == DiscountProductDiscountMode.RECHARGE, "券猫[{}]充值卡只支持充值折扣模式", card.getCardName());
        } else if (QuanMaoCardType.CARD_VOUCHER.equal(card.getCardType())) {
            BizAssert.isTrue(discountMode == DiscountProductDiscountMode.VOUCHERS, "券猫[{}]抵用券只支持抵用券折扣模式", card.getCardName());
        } else {
            BizAssert.throwBizException("券猫服务不支持此折扣模式,只支持充值/折扣券");
        }
    }

    public void onlineVerify(DiscountProduct product, DiscountProductVouchers vouchers) {
        validityVerify(product);

        BizAssert.isTrue(Check.notNull(vouchers.getCounterPrice()), "专柜价不能为空");
        BizAssert.isTrue(Check.notNullAndGtZero(vouchers.getRetailPrice()), "零售价不能为空并且要大于0");
        //BizAssert.isTrue(vouchers.getRetailPrice().scale() <= 2, "零售价只支持最大2位小数设置");
        BizAssert.isTrue(Check.notNullAndGtZero(vouchers.getMaxBuyNumber()), "最大购买数量不能为空并且要大于0");
        // 有效期
        BizAssert.isTrue(DiscountProductVouchersExpirydateStrategy.NO.equal(vouchers.getExpirydateStrategy()), "有效期策略只支持'暂无'");

        QuanMaoCard card = quanMaoCardManager.getById(product.getServiceDataId());
        BizAssert.isTrue(Check.eq(card.getFaceValue(), vouchers.getCounterPrice()), "专柜价格与券码面额[{}]不一致", card.getFaceValue());

    }

    public void onlineVerify(DiscountProduct product, DiscountProductRecharge recharge) {
        validityVerify(product);

        BizAssert.isTrue(Check.notNullOrTrimEmpty(recharge.getAccountInputDescribe()), "账户输入描述不能为空");
        BizAssert.isTrue(Check.notNullOrTrimEmpty(recharge.getAccountInputDescribe()), "账户输入提示不能为空");
        BizAssert.isTrue(Check.notNull(recharge.getCounterPriceType()) && DiscountProductRechargeCounterPriceType.FIXED.equal(recharge.getCounterPriceType()),
                "券码充值价格类型不能为空并且只支持固定价格类型");
        BizAssert.isTrue(Check.notNullAndGtZero(recharge.getCounterPrice()), "专柜价格不能为空");
        BizAssert.isTrue(Check.notNullAndGtZero(recharge.getRetailPrice()), "零售价格不能为空");
        //BizAssert.isTrue(recharge.getRetailPrice().scale() <= 2, "零售价只支持最大2位小数设置");
        BizAssert.isTrue(Check.notNullAndGtZero(recharge.getMaxBuyNumber()), "最大购买数量不能为空并且要大于0");
        QuanMaoCard card = quanMaoCardManager.getById(product.getServiceDataId());
        BizAssert.isTrue(Check.eq(card.getFaceValue(), recharge.getCounterPrice()), "专柜价格与充值面额[{}]不一致", card.getFaceValue());
    }

    public void processOrder(DiscountOrder order, DiscountProductVouchers vouchers, String updateUser) {
        QuanMaoOrderInfo orderInfo = quanMaoExternalService.card(order.getOrderNo(), order.getServiceDataId(), order.getBuyNumber(), "");
        // 记录订单信息
        quanMaoCardOrderManager.save(orderInfo, updateUser);
        // TODO 验证订单结果
        List<DiscountOrderDetail> detailList = orderInfo.getOrderCardPassList().stream().map(cardPass -> {
            DiscountOrderDetail detail = new DiscountOrderDetail();
            detail.setTransNo(orderInfo.getOrderNumber());
            if (Check.notNullOrTrimEmpty(cardPass.getCouponCode())) {
                detail.setVoucherNumber(cardPass.getCouponCode());
            }
            if (Check.notNullOrTrimEmpty(cardPass.getCouponPass())) {
                detail.setVoucherPass(cardPass.getCouponPass());
            }
            if (Check.notNullOrTrimEmpty(cardPass.getExpireTime())) {
//                2020-06-24 00:00:00
                detail.setExpiretime(DateUtil.parseToDate(cardPass.getExpireTime()));
            }
            detail.setIsMainProduct(true);
            detail.setProductId(vouchers.getProductId());
            return detail;
        }).collect(Collectors.toList());
        // 添加详情
        discountOrderDetailManager.add(order, detailList, updateUser);
    }

    public void processOrder(DiscountOrder order, DiscountProductRecharge recharge, String updateUser) {
        // TODO
    }
}
